package com.oschina.wed;

import com.oschina.wed.common.enums.VoucherFlowDirectionEnum;
import com.oschina.wed.common.utils.CommonUtils;
import com.oschina.wed.common.utils.SpringUtil;
import com.oschina.wed.dal.entity.AccountVoucherFlow;
import com.oschina.wed.dal.entity.AccountVoucherSumTmp;
import com.oschina.wed.service.AccountVoucherService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Hashtable;
import java.util.List;

public class Main {
    /**
     * 由于我们已经将调度器交给了Spring管理，
     * 那么此时我们需要做的只是启动容器就好。
     *
     * @param args
     */
    public static void main(String... args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        //生成数据
//        AccountVoucherService accountVoucherService = (AccountVoucherService) context.getBean("accountVoucherService");

        //生成数据
//        accountVoucherService.insertAccountVoucherFlow();

        //java 原生模拟分片计算，单机四分片
//        for (int i = 0; i < 4; i++) {
//            Worker worker = new Worker();
//            worker.setTargetIndex(i);
//            Thread thread = new Thread(worker);
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            thread.start();
//        }

        while (true) {

        }
    }
}

@Component
class Worker extends Thread {
    private Integer targetIndex;

    private AccountVoucherService accountVoucherService;

    public void run() {
        System.out.println("分片：" + targetIndex + "  计算启动....");
        accountVoucherService = (AccountVoucherService) SpringUtil.getBean("accountVoucherService");
        Long start = System.currentTimeMillis();
        boolean runFlag = true;
        while (runFlag) {
            Hashtable<String, Object> query = new Hashtable<>();
            query.put("dataIndex", 4);
            query.put("skipNum", 0);
            query.put("pageSize", 500);
            query.put("targetIndex", targetIndex);
            List<AccountVoucherFlow> data = accountVoucherService.selectForStatics(query);
            if (data.size() < 500)
                runFlag = false;

            Hashtable<Long, AccountVoucherSumTmp> sum = new Hashtable<>();

            String voucherNos = "";

            for (AccountVoucherFlow item : data) {
                if (sum.containsKey(item.getAccountNo())) {
                    switch (VoucherFlowDirectionEnum.getByDirectionCode(item.getAccountDirection())) {
                        case IN:
                            sum.get(item.getAccountNo()).addAmount(item.getAmount());
                            break;
                        case OUT:
                            sum.get(item.getAccountNo()).subAmount(item.getAmount());
                            break;
                    }
                } else {
                    AccountVoucherSumTmp tmp = new AccountVoucherSumTmp();
                    tmp.setAccountNo(item.getAccountNo());
                    tmp.setAccountingDate(new SimpleDateFormat("yyyyMMdd").format(item.getPayDate()));
                    switch (VoucherFlowDirectionEnum.getByDirectionCode(item.getAccountDirection())) {
                        case IN:
                            tmp.setIncomeAmount(item.getAmount());
                            break;
                        case OUT:
                            tmp.setExpendAmount(item.getAmount());
                            break;
                    }
                    sum.put(item.getAccountNo(), tmp);
                }

                voucherNos = voucherNos.concat(item.getVoucherNo().toString()).concat(",");
            }

            for (AccountVoucherSumTmp accountVoucherSumTmp : sum.values()) {
                Hashtable<String, Object> sumVoucher = CommonUtils.convert2HashTable(accountVoucherSumTmp);

                if (accountVoucherService.updateAccountVoucherSum(sumVoucher) <= 0) {
                    accountVoucherService.insertAccountVoucherSum(sumVoucher);
                }
            }

            accountVoucherService.update2Staticed(voucherNos.substring(0, voucherNos.length() - 1));
        }
        Long end = System.currentTimeMillis() - start;
        System.out.println("分片：" + targetIndex + "  累计工作耗时：" + end + "ms");
    }

    public Integer getTargetIndex() {
        return targetIndex;
    }

    public void setTargetIndex(Integer targetIndex) {
        this.targetIndex = targetIndex;
    }

    public AccountVoucherService getAccountVoucherService() {
        return accountVoucherService;
    }

    public void setAccountVoucherService(AccountVoucherService accountVoucherService) {
        this.accountVoucherService = accountVoucherService;
    }
}